home *** CD-ROM | disk | FTP | other *** search
- /*
- * structrid.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* STRUCTRID: program takes input PCC, removes structures whose total
- * length of lines or bounding box area is below or above
- * the chosen thresholds, and writes output PCC
- * usage: structrid infile outfile [-ll] [-hl] [-la] [-ha] [-L]
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "pcc2.h" /* header file for PCC programs */
- extern void print_sos_lic ();
-
- unsigned char *fcCode; /* code storage */
- long nByteCode; /* no. bytes in code storage */
-
- int tlc3rid (struct attributes *, long, struct structures *, long *,
- long, long, long, long);
- int usage (short);
- int input (int, char **, long *, long *, long *, long *);
-
- main (argc, argv)
- int argc;
- char *argv[];
-
- {
- long width, height; /* image size */
- long lowLength, highLength, /* range of lengths to retain */
- lowArea, highArea; /* range of areas to retain */
- struct attributes *attr; /* level 1 attributes */
- long nAttr; /* no. of line structures in attr. array */
- struct structures *structs; /* level 3 line structures */
- long nStructs; /* no. of connected structures in image */
-
- if ((input (argc, argv, &lowLength, &highLength, &lowArea, &highArea))
- < 0)
- return (-1);
-
- lowLength *= 10; /* lengths are scaled */
- highLength *= 10;
-
- /* open input PCC file */
- if (pccread (argv[1], &fcCode, &nByteCode, &width, &height) == -1)
- exit (1);
- printf ("image size: %dx%d, PCC length = %d\n",
- width, height, nByteCode);
-
- /* construct tables of PCC decodes */
- pccdecodes ();
-
- /* construct TLC level 1 array of attributes */
- tlc1attr (&attr, &nAttr);
- printf ("%d level 1 line features\n", nAttr);
-
- /* find level 3 connected structures */
- tlc3structs (attr, nAttr, &structs, &nStructs);
- printf ("%d level 3 structures\n", nStructs);
-
- /* determine level 3 features */
- tlc3feats (attr, nAttr, structs, nStructs);
- tlc3rid (attr, nAttr, structs, &nStructs,
- lowLength, highLength, lowArea, highArea);
- printf ("%d level 3 structures remaining, %d code bytes.\n",
- nStructs, nByteCode);
-
- /* write out PCC file */
- if (nStructs > 0)
- pccwrite (argv[2], fcCode, nByteCode, width, height);
- else
- printf ("No output file -- all structures filtered out.\n");
-
- return (0);
- }
-
-
-
- /* TLC3RID: function removes any level 3 structures above or below threshold
- * usage: tlc3rid (attr, nAttr, structs, &nStructs,
- * lowLength, highLength, lowArea, highArea)
- */
-
- int
- tlc3rid (attr, nAttr, structs, nStructs, lowLength, highLength,
- lowArea, highArea)
- struct attributes *attr; /* level 1 attributes */
- long nAttr; /* no. level 1 attributes */
- struct structures *structs; /* level 3 attributes */
- long *nStructs; /* no. level 3 attributes */
- long lowLength, highLength, /* length range to retain (*10) */
- lowArea, highArea; /* area range to retain */
- {
- long strtCode, endCode, /* bounds of code for structure */
- iStopByte, /* position of STOPBYTE */
- nStructsOut, /* no. of structures after removal */
- iStructs, /* level 3 increment */
- iCode, /* input PCC incrementor */
- iOut; /* output PCC incrementor */
- struct structures strct; /* level 3 structure */
- long lx, ly, /* lengths of bounding box */
- area; /* area of bounding box */
-
- /* find position of STOPCODE (I'm inconsistent I think in putting 4 bytes
- * trailing this or not, so we'll find it) */
- for (iStopByte = nByteCode - 1; iStopByte > 0; --iStopByte)
- if (fcCode[iStopByte] == STOPCODE)
- break;
-
- /* read code, and write code which is not deleted */
- nStructsOut = 0;
- for (iStructs = 0, iOut = 0; iStructs < *nStructs; iStructs++) {
- strct = structs[iStructs];
- strtCode = attr[strct.iAttr].iByteCode - 5;
- endCode = (iStructs + 1 < *nStructs) ?
- attr[structs[iStructs + 1].iAttr].iByteCode - 6 : iStopByte - 1;
- lx = (strct.box.max.x - strct.box.min.x);
- ly = (strct.box.max.y - strct.box.min.y);
- if (lx == 0)
- lx = 1;
- if (ly == 0)
- ly = 1;
- area = lx * ly;
- if (area < 0)
- area *= -1;
- if (strct.length >= lowLength && strct.length < highLength
- && area >= lowArea && area < highArea) {
- nStructsOut++;
- for (iCode = strtCode; iCode <= endCode; iCode++)
- fcCode[iOut++] = fcCode[iCode];
- }
- }
-
- for (iCode = iStopByte; iCode < nByteCode; iCode++)
- fcCode[iOut++] = fcCode[iCode];
- *nStructs = nStructsOut;
- nByteCode = iOut;
- return (0);
- }
-
-
-
- /* USAGE: function gives instructions on usage of program
- * usage: usage (flag)
- * When flag is 1, the long message is given, 0 gives short.
- */
-
- int
- usage (flag)
- short flag; /* flag =1 for long message; =0 for short message */
- {
-
- /* print short usage message or long */
- printf ("USAGE: structrid infile outfile [-ll] [-hl] [-la] [-ha] [-L]\n");
- if (flag == 0)
- return (-1);
-
- printf ("\nstructrid filters line structures, that is, objects\n");
- printf ("made up of one or many connected line segments, removing\n");
- printf ("those whose features are outside of the range given.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" infile: input filename (PCC) \n");
- printf (" outfile: output filename (PCC) \n\n");
- printf ("OPTIONS:\n");
- printf (" -ll LOW LENGTH: lowest length structure to retain.\n");
- printf (" -hl HIGH LENGTH: highest length structure to retain.\n");
- printf (" -la LOW AREA: lowest bounding box of structure to retain.\n");
- printf (" -ha HIGH AREA: highest bounding box of structure to retain.\n");
- printf (" -L: print Software License for this module\n");
-
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, &lowLength, &highLength,
- * &lowArea, &highArea)
- */
-
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- int
- input (argc, argv, lowLength, highLength, lowArea, highArea)
- int argc;
- char *argv[];
- long *lowLength, *highLength; /* lowest and highest lengths to retain */
- long *lowArea, *highArea; /* lowest and highest areas to retain */
- {
- long n;
-
- static char *llString = "-ll";
- static char *hlString = "-hl";
- static char *laString = "-la";
- static char *haString = "-ha";
-
- if (argc < 3)
- USAGE_EXIT (1);
-
- *lowLength = *lowArea = 0;
- *highLength = *highArea = 100000000;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-ll") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *lowLength = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-hl") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *highLength = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-la") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *lowArea = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-ha") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *highArea = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (0);
- }
-
- return (0);
- }
-